/**
 * Created by zhudaohui on 2017/12/26.
 */

import React, {PureComponent}  from "react";
import {AutoComplete, Icon, Input, Spin, Select} from '../../antd'
import Http from "../utils/http"

const Option = Select.Option;

/**
 * 配置参数说明：
 * url: 必选，查询url，注意是post请求
 * searchField: 必选，后端接受前端参数里面的属性名称，比如控制范围编码自动联想框,那么code是searchField
 * displayField: 必选，后端返回的数据模型中需要展示到下拉框的属性名称
 * valueField: 必须，后端返回的数据模型中需要保存到服务端的值
 * searchParams: 可选，如果除了searchField参数外还有额外的参数需要传递，使用该配置
 *
 */
class AutoCompleteSelect extends PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            dataSource : [],
            value : this.props.value,
            loading: props.loading || false,
        };

        this.lastDoRemoteSearchExplicitlyValue = null;
    }

    handleSearch = (value, afterSearchFunc) => {
        if (!value) {
            return;
        }
        const {
            minimumSearchLength,
            displayField,
            searchField ,
            searchParams} = this.props;
        if (minimumSearchLength && value.length < minimumSearchLength) {
            //输入的字符长度没有超过最小值不进行搜索
            return;
        }

        let params = Object.assign({}, searchParams ? searchParams : {});

        params[searchField] = value;
        const postOption =  {
            url: this.props.url,
            params: params
        }

        this.setState({loading:true});
        Http.post(postOption)
            .then(result => {
                this.setState({loading:false});
                let resultArray;
                if (result && result.code === 0 && result.data) {
                    if (result.data.rows && result.data.rows.length > 0) {//paginated result
                        resultArray = result.data.rows;
                    } else if (result.data.data) {
                        resultArray = result.data.data
                    } else {
                        resultArray = result.data
                    }
                }

                if (resultArray && resultArray.length > 0) {
                    //setState method will trigger component invoking render method
                    this.setState({
                        dataSource: resultArray
                    });
                } else {
                    this.setState({
                        dataSource: []
                    });
                    console.log("AutoCompleteSelect search result is empty");
                }

                if(afterSearchFunc) {
                    afterSearchFunc(value);
                }

                if (this.props.onResponseArrived) {
                    this.props.onResponseArrived(this.state.dataSource);
                }
            })
            .catch((error) => {
                console.log(`AutoCompleteSelect error: ${error}`);
                this.setState({loading:false});
            });
    }

    reset = () => {
        this.triggerChange(null);
    }

    handleChange = (value) => {
        this.triggerChange(value);
    }

    // handleSelect = (value) => {
    //     this.triggerSelect(value);
    // }

    handleSelect = (value, option) => {
        this.setState({
            value: value
        });
        const dataSource = this.state.dataSource;
        let obj = null;
        if(dataSource && dataSource.length > 0) {
            for (let i = 0; i< dataSource.length; i++) {
                let item = dataSource[i];
                if (value === item[this.props.valueField]) {
                    obj = item;
                    break;
                }
            }
        }
        if(this.props.onSelect) {
            this.props.onSelect(value, option, obj);
        }
    }

    triggerChange = (changedValue) => {
        this.setState({
            value: changedValue
        });

        // Should provide an event to pass value to Form.
        //Here this.props.onChange is from Form not defined by us
        const onChange = this.props.onChange;
        if (onChange) {
            onChange(changedValue);
        }
    }

    triggerSelect = (changedValue) => {
        this.setState({
            value: changedValue
        });

        // Should provide an event to pass value to Form.
        //Here this.props.onChange is from Form not defined by us
        const onSelect = this.props.onSelect;
        if (onSelect) {
            onSelect(changedValue);
        }
    }

    componentWillReceiveProps = (nextProps, nextContext) => {
        const _this = this;
        if(this.state.value != nextProps.value) {
            if(nextProps.value && nextProps.value.doRemoteSearchExplicitly) {
                if(this.lastDoRemoteSearchExplicitlyValue != nextProps.value.value) {
                    this.lastDoRemoteSearchExplicitlyValue = nextProps.value.value;
                    this.handleSearch(nextProps.value.value, (searchedValue) => {
                        _this.setState({value: searchedValue});
                    });
                }
            } else {
                this.setState({value: nextProps.value});
            }
        }

        if (this.state.dataSource && nextProps.dataSource
            && this.state.dataSource.length != nextProps.dataSource.length) {
            this.setState({
                dataSource: nextProps.dataSource
            });
        }
    }

    render() {
        const {displayField, valueField} = this.props;
        const {dataSource, value} = this.state;
        const renderOption = (item) => {
            return (
                <Option key={item[valueField]} value={item[valueField]}>
                    {item[valueField] + ' ' + item[displayField]}
                </Option>
            );
        }

        return (
            <Spin size="small" spinning={this.state.loading}>
            <AutoComplete
                value={value}
                dataSource={dataSource.map(renderOption)}
                onSelect={this.handleSelect}
                onSearch={this.handleSearch}
                onChange={this.handleChange}
                placeholder={this.props.placeholder || '输入关键词搜索'}
                style={this.props.style}
                allowClear={true}
                disabled={this.props.disabled}
            >
                {/*<Input suffix={<Icon type="search" className="certain-category-icon" />} />*/}
            </AutoComplete>
            </Spin>
        );
    }
}

export default AutoCompleteSelect